#pragma once

#include "dcmtk/dcmnet/dimse.h"
#include "dcmtk/dcmtls/tlslayer.h"

#include "inetwork.h"


class Network final
    :public INetwork
{
public:
    Network::Network();

    Network::~Network();

public:
    bool
    EchoRequest(
        const ServerInfo&              aServer
    ) override;

    bool
    StoreRequest(
        const ServerInfo&              aServer,
        const std::string&             aDCMFile
    ) override;

    bool
    StoreRequest(
        const ServerInfo&              aServer,
        std::shared_ptr<IDataSet>      aDataSet
    ) override;

    bool
    WorklistRequest(
        const ServerInfo&              aServer,
        const WorklistInfo&            aWorklist
    ) override;

    void
    BindWorklistCallback(
        PWorklistCallback              aCallBack
    ) override;

    void
    BindStoreCallback(
        PStoreCallback                 aCallBack
    ) override;

    bool
    SetTLS(
        const std::string&            aSeedFile,
        const std::string&            aPrivateKey,
        const std::string&            aCertifiFile,
        const std::string&            aPassPhrase,
        const CertificateVerification     aCertify
    ) override;

    std::string
    GetOpenSSLVersion()
    override;

private:
    bool
    PrivConnection(
        const ServerInfo&              aServer
    );

    bool
    PrivRelease(
        const ServerInfo&              aServer
    );

    static void
    PrivStoreCallback(
        void* aCallbackData,
        T_DIMSE_StoreProgress*         aProgress,
        T_DIMSE_C_StoreRQ*             aRequest
    );

    static void
    PrivWorklistCallback(
        void* aCallbackData,
        T_DIMSE_C_FindRQ*              aRequest,
        int                            aResponseCount,
        T_DIMSE_C_FindRSP*             aResponse,
        DcmDataset*                    aResponseIdentifiers
    );

    bool
    PrivSupportTLS();

private:
    T_ASC_Association*                 myAssoc;
    T_ASC_Parameters*                  myASCParams;
    T_ASC_Network*                     myNet;
    static PWorklistCallback           myWorklistCallback;
    static PStoreCallback              myStoreCallback;
    std::string                        mySeedFile;
    std::string                        myPrivateKey;
    std::string                        myCertifiFile;
    std::string                        myPassPhrase;
    CertificateVerification            myCertify;
    DcmTLSTransportLayer*              myTLS;
};
